package org.alps.demo.sentinel;

import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.SphU;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;

import java.util.ArrayList;
import java.util.List;

/**
 * @date 2021-04-03
 * @author zkw
 */
public class HelloWord {

    /**
     * 定义规则
     * 规则 + 规则管理器 + 对应的异常
     * 流控规则、流控规则管理器、流控异常
     * 降级规则、降级规则管理器、降级异常
     */
    public static void initFlowRules() {
        List<FlowRule> rules = new ArrayList<>();
        FlowRule rule = new FlowRule();
        /**
         * resource:资源名，即限流规则的作用对象
         * 规则一定要绑定到对应的资源上（通过资源名称进行绑定，名称要一致）
         * 规则可以加到多个资源上
         * 一个资源也可以有多个规则：如流控规则、降级规则、热点规则、黑白名单规则等
         */
        rule.setResource("helloword");
        //grade:限流阈值类型，QPS 或线程数
        rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
        //定义资源 helloword 每秒最多只能通过 20 个请求
        rule.setCount(20);
        rules.add(rule);

        //规则管理器（持久化到内存中）
        FlowRuleManager.loadRules(rules);
    }

    public static void initDegradeRules() {
        List<DegradeRule> rules = new ArrayList<>();
        DegradeRule rule = new DegradeRule();
        rule.setResource("org.alps.demo.sentinel.controller.IndexController:degrade");
        //grade:限流阈值类型，QPS 或线程数
        rule.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_COUNT);
        rule.setCount(2);
        rules.add(rule);
        DegradeRuleManager.loadRules(rules);
    }

    public static void main(String[] args) {

        //1.引入依赖
        //2.定义资源

        //初始化规则
        initFlowRules();

        while (true) {
            Entry entry = null;
            try {
                //2.1 定义资源名称
                entry = SphU.entry("helloword");
                //2.2 执行资源逻辑代码
                System.err.println("helloworld: 访问数据库");
                System.err.println("helloworld: 访问远程redis");
                System.err.println("helloworld: 数据库持久化操作");
                Thread.sleep(20);

            } catch (BlockException e) {
                System.err.println("要访问的资源被流控了，执行流控逻辑");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                if (entry != null) {
                    entry.exit();
                }
            }

            Entry entry2 = null;
            try {
                //2.1 定义资源名称
                entry2 = SphU.entry("helloredis");
                //2.2 执行资源逻辑代码
                //System.err.println("helloworld: 访问数据库");
                System.err.println("helloworld: 访问远程redis");
                //System.err.println("helloworld: 数据库持久化操作");
                Thread.sleep(20);

            } catch (BlockException e) {
                System.err.println("要访问的资源被流控了，执行流控逻辑");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                if (entry2 != null) {
                    entry2.exit();
                }
            }
        }
        //3.定义规则


        //4.查看结果
    }
}
